package com.thinkfit.jy.view

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.DashPathEffect
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PathMeasure
import android.graphics.Point
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import com.thinkfit.jy.R

class TrackView(context: Context) : View(context) {

    constructor(context: Context, attrs: AttributeSet) : this(context) {

        lineSpace = dp2px(20)
        initPaint()

    }

    //内部线画笔  内部跑道线
    lateinit var innerPaint: Paint

    //中间线画笔 中间跑道线
    lateinit var centerPaint: Paint

    //外部线画笔 外部跑道线
    lateinit var outPaint: Paint

    //跑道背景色
    lateinit var bgPaint: Paint

    //中间文字画笔
    lateinit var centerTextPaint: Paint

    //用户名画笔
    lateinit var textPaint: Paint

    //名字背景画笔
    lateinit var mTextBgPaint: Paint

    //icon 画笔
    lateinit var iconPaint: Paint

    //已运动距离画笔
    lateinit var dstPaint: Paint

    //外部线path
    lateinit var outPath: Path

    //中间线path
    lateinit var centerPath: Path

    //中间运动片段path
    private val dstPath = Path()

    //跑道背景path
    lateinit var bgPath: Path

    //内部线path
    lateinit var innerPath: Path

    //内部线颜色
    private val innerColor = Color.BLACK

    //中间线颜色
    private val centreColor = Color.GRAY

    //最外部线颜色
    private val outColor = Color.BLACK

    //跑道线之间间隔
    private var lineSpace = 0

    //内部矩形
    lateinit var innerRect: RectF  //内部矩形
    lateinit var innerRectL: RectF  //内部矩形
    lateinit var innerRectR: RectF

    //中间矩形
    lateinit var centerRect: RectF //中间矩形
    lateinit var centerRect1: RectF  //中间矩形
    lateinit var centerRect2: RectF

    //外部矩形
    lateinit var outRect: RectF  //外部矩形
    lateinit var outRect1: RectF  //外部矩形
    lateinit var outRect2: RectF

    //测量中间文字用
    private val textBounds = Rect()

    //画布宽高
    private var mWidth = 0  //画布宽高
    private var mHeight = 0

    //
    private val mContext: Context? = null

    //是否初始化完成 防止重复测量
    private var inited = false

    //
    lateinit var icon: Bitmap

    //
    lateinit var startBp: Bitmap

    //起点图片坐标
    private val startPoint = Point()

    //测量已运动路径用
    var measure = PathMeasure()

    //中间跑道路径的实际长度
    var pathLength = 0f

    var singleDistance = 0f //单人已运动距离

    private val sumDis = 400 //操场总距离

    //用来记录path上某距离处坐标
    var point = FloatArray(2)


    private fun initPaint() {

        innerPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
            color = innerColor
            style = Paint.Style.STROKE
            strokeWidth = dp2px(2).toFloat()
        }

        centerPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
            color = centreColor
            style = Paint.Style.STROKE
            strokeWidth = dp2px(1).toFloat()
        }

        //虚线 参数1：{虚线长度，虚线间隔} 参数2：开始的偏移量
        val dashPathEffect =
            DashPathEffect(
                floatArrayOf(
                    dp2px(10).toFloat(),
                    dp2px(5).toFloat()
                ), 0f
            )
        centerPaint.pathEffect = dashPathEffect


        outPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
            color = outColor
            style = Paint.Style.STROKE
            strokeWidth = dp2px(2).toFloat()
        }

        bgPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
            color = Color.parseColor("#55ffffff")
            style = Paint.Style.STROKE
            strokeWidth = (lineSpace * 2).toFloat()
        }

        centerTextPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
            color = Color.BLUE
            strokeWidth = sp2px(2).toFloat()
            textSize = sp2px(30).toFloat()
        }

        textPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
            color = Color.BLACK
            textSize = sp2px(10).toFloat()
        }

        mTextBgPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
            color = -0x4c080809
            style = Paint.Style.FILL_AND_STROKE
            strokeWidth = sp2px(10 + 4).toFloat()
            strokeCap = Paint.Cap.ROUND
        }


        iconPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
            style = Paint.Style.STROKE
            strokeWidth = 1f
        }

        dstPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
            style = Paint.Style.STROKE
            strokeWidth = dp2px(5).toFloat()
            strokeCap = Paint.Cap.ROUND
            color = Color.BLUE
        }

    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //可能会被多次测量
        if (!inited) {
            mWidth = MeasureSpec.getSize(widthMeasureSpec)
            mHeight = MeasureSpec.getSize(heightMeasureSpec)
            inited = true
        }
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        initRect()
    }

    private fun initRect() {
        //跑道距边缘的Padding

        //跑道距边缘的Padding
        val leftPadding = dp2px(20)
        val rightPadding = dp2px(20)
        val topPadding = dp2px(10)
        val bottomPadding = dp2px(10)


        //画外面
        //画外面
        val outWidth = outPaint.strokeWidth.toInt()

        //最外面跑道线
        val x = outWidth / 2 + leftPadding
        val y = outWidth / 2 + topPadding
        val x1 = width - outWidth / 2 - rightPadding
        val y1 = height - outWidth / 2 - bottomPadding
        val outSpace = y1 - y //实际高度

        outRect = RectF(x.toFloat(), y.toFloat(), x1.toFloat(), y1.toFloat())
        //辅助矩形1
        val ox1 = x
        val oy1 = y
        val ox11 = x + outSpace
        val oy11 = y + outSpace
        outRect1 = RectF(ox1.toFloat(), oy1.toFloat(), ox11.toFloat(), oy11.toFloat())

        //辅助矩形2
        val ox2 = x1 - outSpace
        val oy2 = y
        val ox12 = x1
        val oy12 = y1
        outRect2 = RectF(ox2.toFloat(), oy2.toFloat(), ox12.toFloat(), oy12.toFloat())

        //闭合
        outPath = Path()
        outPath.addArc(outRect2, 270f, 180f)
        outPath.arcTo(outRect1, 90f, 180f)
        outPath.lineTo((x1 - outSpace / 2).toFloat(), y.toFloat())

        //画中间-中间和里面都是重复上面步骤 只是矩形长宽等距离缩小

        //画中间
        val cx = x + lineSpace
        val cy = y + lineSpace
        val cx1 = x1 - lineSpace
        val cy1 = y1 - lineSpace

        //中间矩形实际高度
        val centerHeight = cy1 - cy
        centerRect = RectF(cx.toFloat(), cy.toFloat(), cx1.toFloat(), cy1.toFloat())

        //辅助矩形1
        val cx2 = cx
        val cy2 = cy
        val cx12 = cx + centerHeight
        val cy12 = cy + centerHeight
        centerRect1 = RectF(cx2.toFloat(), cy2.toFloat(), cx12.toFloat(), cy12.toFloat())

        //辅助矩形2
        val cx3 = cx1 - centerHeight
        val cy3 = cy
        val cx13 = cx1
        val cy13 = cy1
        centerRect2 = RectF(cx3.toFloat(), cy3.toFloat(), cx13.toFloat(), cy13.toFloat())

        //闭合
        centerPath = Path()
        centerPath.addArc(centerRect2, 270f, 180f)
        centerPath.arcTo(centerRect1, 90f, 180f)
        centerPath.lineTo((cx1 - centerHeight / 2).toFloat(), cy.toFloat())

        startPoint.x = cx1 - centerHeight / 2
        startPoint.y = cy

        //画里面


        //画里面
        val ix = cx + lineSpace
        val iy = cy + lineSpace
        val ix1 = cx1 - lineSpace
        val iy1 = cy1 - lineSpace
        //里面矩形实际高度
        val innerHeight = iy1 - iy
        innerRect = RectF(ix.toFloat(), iy.toFloat(), ix1.toFloat(), iy1.toFloat())

        //辅助矩形1
        val ix2 = ix
        val iy2 = iy
        val ix12 = ix + innerHeight
        val iy12 = iy + innerHeight
        innerRectL = RectF(ix2.toFloat(), iy2.toFloat(), ix12.toFloat(), iy12.toFloat())
        //辅助矩形2
        val ix3 = ix1 - innerHeight
        val iy3 = iy
        val ix13 = ix1
        val iy13 = iy1
        innerRectR = RectF(ix3.toFloat(), iy3.toFloat(), ix13.toFloat(), iy13.toFloat())

        //闭合
        innerPath = Path()
        innerPath.addArc(innerRectR, 270f, 180f)
        innerPath.arcTo(innerRectL, 90f, 180f)
        innerPath.lineTo((ix1 - innerHeight / 2).toFloat(), iy.toFloat())

        bgPath = centerPath

        //测量路径
        measure.setPath(centerPath, false)
        pathLength = measure.length

        icon = BitmapFactory.decodeResource(context.resources, R.drawable.app_not_login)
        startBp = BitmapFactory.decodeResource(context.resources, R.drawable.img_mian_luminance)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        //跑道背景
        canvas.drawPath(bgPath, bgPaint)
        //三条跑道线

        //三条跑道线
        canvas.drawPath(outPath, outPaint)
        canvas.drawPath(centerPath, centerPaint)
        canvas.drawPath(innerPath, innerPaint)

        //起点图片
        canvas.drawBitmap(
            startBp!!,
            (startPoint.x - (startBp.width * 2)).toFloat(),
            (startPoint.y - (startBp.height * 2)).toFloat(),
            iconPaint
        )

        //单人模式
        //画已运动距离路径，已运动的path
        dstPath.reset()
        measure.setPath(centerPath, false)
        //拿到从0开始到距离为singleDistance 长度的 path片段
        measure.getSegment(0f, getPosition(singleDistance), dstPath, true)
        canvas.drawPath(dstPath, dstPaint)
        //拿到centerPath 上距离为 singleDistance 的终点坐标
        measure.getPosTan(getPosition(singleDistance), point, null)
        //画头像
        val halfWidth = icon.width / 2
        val halfHeight = icon.height / 2
        canvas.drawBitmap(icon, point[0] - halfWidth, point[1] - halfHeight, iconPaint)
        //画名字
        drawName(canvas, point, halfHeight, (""+getPosition(singleDistance)));
        //...

    }

    private fun drawName(canvas: Canvas, point: FloatArray, halfHeight: Int, name: String) {
        //画名字
        //头像顶部中心坐标
        val x = point[0]
        val y = point[1] - halfHeight
        //名字距离头像的间隔
        val spacing = dp2px(4).toFloat()
        textBounds.setEmpty()
        //计算给定字符串的边界，并将结果保存在给定的 textBounds 对象中。
        textPaint.getTextBounds(name, 0, name.length, textBounds)
        //画 文字坐标
        val ty: Float
        val tx: Float = x - (textBounds.width() / 2)
        //确定基线-不了解的可以去了解下
        val metricsInt = textPaint.fontMetricsInt
        val dy = (metricsInt.bottom - metricsInt.top) / 2 - metricsInt.bottom
        ty = y + dy - spacing
        //用于给文字加个背景 文字的中间水平线Y
        val ly = ty - (textBounds.height() / 2)
        canvas.drawLine(tx, ly, tx + textBounds.width(), ly, mTextBgPaint)
        canvas.drawText(name, tx, ty, textPaint)
    }

    /**
     * 预设：跑道 400米
     * 通过实际距离 经过和预设跑道距离 转换，得到 distance 在跑道上的具体距离，进而确定位置
     */
    private fun getPosition(distance: Float): Float {
        return pathLength * distance / sumDis % pathLength
    }

    fun sp2px(spValue: Int): Int {
        val fontScale = resources.displayMetrics.scaledDensity
        return (spValue * fontScale + 0.5f).toInt()
    }

    fun dp2px(dp: Int): Int {
        val scale = resources.displayMetrics.density
        return (dp * scale + 0.5f).toInt()
    }

    fun setPosition(distance: Float) {
        println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx  distance : "+distance);
        singleDistance = distance
        println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx  singleDistance : "+singleDistance);
        invalidate()
    }

}
